Golang实现SOAP客户端的经验总结 您所在的位置:网站首页 youArefreeto go Golang实现SOAP客户端的经验总结

Golang实现SOAP客户端的经验总结

2023-12-28 06:48| 来源: 网络整理| 查看: 265

引言

SOAP是一种“简单”的基于XML的协议,在10多年前流行过一阵。与现在行其道的基于JSON协议的restFul API相比,SOAP无疑要笨重许多。

如果项目的开发语言是.net或者Java,那还好还,因为IDE有方便的内置功能来解析SOAP服务的WSDL文件,自动生成Client的相关代码。但如果是用Golang,那就麻烦了。

下面说说SOAP的不同之处,或者说麻烦的地方。

SOAP的不同之处 Request/Response结构复杂,嵌套层级多且深

下面是一个Request Body的示例,这个XML是必须指定特定的namespace的。API的验证密钥信息,也是要写在Request Body中。

通常soapenv:Body部分通常是会更加复杂的,如果没有工具支持,纯手工来写,累人不说,还容易出错。

Header的设置 Content-Type: text/xml; charset="utf-8" SOAPAction: http://www.id3global.com/ID3gWS/2013/04/IGlobalAuthenticate/AuthenticateSP

header中的Content-Type是application/xml, 可不要下意识的写成application/json哦。而SOAPAction这个header就是特别注意了,需要设置成要调用的action,而且需要注意的是,不同的action的baseUrl可能是不一样的。相比而言,restFul的API可没这么多坑。

multiple part的reponse

虽说大部分时候,SOAP的返回数据是XML格式,但有时会是如下这种multiple part的格式,解析起来也是需要些功夫的。

--uuid:6d335978-5c93-40b7-b5c4-3acc067e3d8c+id=302 Content-ID: Content-Transfer-Encoding: 8bit Content-Type: application/xop+xml;type="text/xml" --uuid:6d335978-5c93-40b7-b5c4-3acc067e3d8c+id=302-- 时间的反序列化与Golang的time.Time类型

Golang的time.Time类型在unmarshal时是需要time zone的信息的,简单来说就是结尾至少要有个Z,例:2021-09-23T14:55:43.835Z。如果没有time zone信息,如:2024-07-13T00:00:00,那么,或者你不用time.Time而用string,再或者就是重写UnmarshalXML的方法了。

解决方案

写了这么多,你也会发现,如果没有现成的工具,自己要处理的细节不是一般的多。

本着技术领域没有新问题,或者说你永远不会是第一个遇到这个问题的人,我开始搜索之路,不得不说搜索还是要google!

我通过medium上的一篇文章,找到心仪的工具, gowsdl,你可以用这个工具方便的生成模板代码:

gowsdl [options] myservice.wsdl

但是呢,我不建议你直接使用生成的代码,而只是使用它定义的结构,自己再重新封装一个client,原因是:

通常一个wsdl里定义的action特别多,而你只需要用其中一两个action 再则,生成的代码关于时间字段默认使用的还是time.Time,建议还是自己手动改成gowsdl中定义好的XSDDateTime。想想也是好笑,为啥不直接用XSDDateTime呢。

总体来说,生成的代码也是有很多优点的:

可以识别出Enum,会生成特定的类型及值。 可以识别出每个action对应的SOAPAction的http header

最后,再提一点,不知道是我集成的第三方服务的SOAP协议特别古老了,还是这个库有bug,总之,是在处理multiple part的response时,有一些检查的逻辑没过,我是提了一个PR,虽说目前还没人处理,但确实有些tricky。

在这种情况,就涉及到另一个问题,在用go mod管理第三方包的时候,如何hotfix在引用包中发现的问题?

其实,主要是可以分3步:

在github上,fork一个自己的repo 改动相关代码,然后Push一个新的tag 但因为这个Module的引用名称还要保持原来的名字,如果用自己克隆的repo的,就会遇到下面这个错误 go: github.com/ksloveyuan/[email protected]: parsing go.mod: module declares its path as: github.com/hooklift/gowsdl but was required as: github.com/ksloveyuan/gowsdl

我没深入调查原因,但感觉是和go.mod有关。还是那句话,你不会是第一个遇到这个问题人,解决方法是使用go.mod中的replace功能,在go.mod文件的最后,加入下面这行就可以修复这个错误了

replace github.com/hooklift/gowsdl v0.5.0 => github.com/ksloveyuan/gowsdl v0.5.1


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有